﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kokomo.PeInspector.Reflection.Disassembly;
using System.Reflection;
using System.Collections;
using System.Windows;
using System.Threading;
using System.Windows.Media;
using Kokomo.Environment.Documents;

namespace Kokomo.PeInspector.Reflection
{
	class DependencyGraphViewModel : NotifierObject
	{
		public IMetadataHost Host { get; private set; }
		public TreeNodeViewModel RootNode { get; private set; }
		public DependencyGraph Graph { get; private set; }

		public DependencyGraphViewModel(
			IMetadataHost host,
			DependencyGraph graph,
			UiString heading
			)
		{
			if (host == null) throw new ArgumentNullException("host");
			if (graph == null) throw new ArgumentNullException("graph");

			this.Host = host;
			this.Graph = graph;

			this.RootNode = this.CreateMemberNode(graph.RootMember, heading);
		}

		private TreeNodeViewModel CreateMemberNode(MemberInfo member, UiString heading = null)
		{
			MemberViewInfo viewInfo = MemberViewInfo.GetMemberViewInfo(member);
			Func<ProgressInfo, IEnumerable<TreeNodeViewModel>> itemsSourceDelegate = (progress) => this.CreateMemberItemsSource(member, progress);

			if (heading == null) heading = UiString.FromString(viewInfo.LongHeading);
			TreeNodeViewModel node = new TreeNodeViewModel(
				AssemblyAnalyzerEditor.MetadataIconProvider.GetImage(viewInfo.IconKey),
				heading,
				member) { ItemsSourceDelegate = itemsSourceDelegate };

			return node;
		}

		private IEnumerable<TreeNodeViewModel> CreateMemberItemsSource(MemberInfo member, ProgressInfo progress)
		{
			var dependencies = this.Graph.DependencyDelegate(member, progress);
			if (dependencies == null) return null;
			List<TreeNodeViewModel> nodes = new List<TreeNodeViewModel>();
			foreach (var dependency in dependencies)
			{
				TreeNodeViewModel node = this.CreateMemberNode(dependency);
				nodes.Add(node);
			}

			return nodes;
		}
	}
}
